<template>
  <div class="wrap">
    <template>
      <div class="d-flex align-items-center">
        <query-list
          v-model="params.pointCloudList"
          :description="$t('message.PointCloud.selectPointCloud')"
          :tipMsg="$t('message.PointCloud.selectPointCloud')"
          @removeItem="removeSelect">
        </query-list>
      </div>
      <div class="d-flex align-items-center">
        <label class="el-form-item__label">{{$t('message.PointCloud.reduction')}}:</label>
        <el-input v-model="params.reduction.variableValue"
                  :min="0"
                  :max="100"
                  type="number"
                  :rounded="true"
                  @change="changeReduction"/>
        <label class="el-form-item__label">{{ $t('message.PointCloud.percent') }}</label>
      </div>
      <div class="reductionRange">
        <input type="range"
               id="ReductionScrollValue"
               v-model="params.reductionScrollValue"
               :min="params.reductionBoundary.min"
               :max="params.reductionBoundary.max"
               :step="1"
               @change="changeReductionScrollValue"/>
      </div>
      <div class="d-flex align-items-center">
        <label class="el-form-item__label">{{$t('message.PointCloud.targetPoints')}}:</label>
        <el-input v-model="params.target.variableValue"
                  :boundary="params.targetBoundary"
                  type="number"
                  :rounded="true"
                  @change="changeTarget"/>
      </div>
      <div class="d-flex align-items-center">
        <label class="el-form-item__label">{{$t('message.PointCloud.originPoints')}}:</label>
        <el-input v-model="params.origin"
                  type="number"
                  :disabled="true"/>
      </div>

      <div class="collapse-panel">
        <div class="collapse-a">
          <div>
            <p><b>{{ $t('message.PointCloud.samplingType') }}</b></p>
          </div>
          <div :id="collapseId1" @click="foldClick1">
                    <span class="cursor-pointer" :class="[{'cursor-pointer': !disabled1}]">
                        <i :class="['fa', collapse1 ? 'fa-angle-up' : 'fa-angle-down']"/>
                    </span>
          </div>
        </div>
        <div v-show="!collapse1">
          <div>
            <el-checkbox v-model="params.samplingSelected.random"
                         :label="$t('message.PointCloud.random')"
                         @change="changeSamplingType(SamplingType.RANDOM)"/>
          </div>
          <div>
            <el-checkbox v-model="params.samplingSelected.curvature"
                         :label="$t('message.PointCloud.curvature')"
                         @change="changeSamplingType(SamplingType.CURVATURE)"/>
          </div>
          <div>
            <el-checkbox v-model="params.samplingSelected.uniform"
                         :label="$t('message.PointCloud.uniform')"
                         @change="changeSamplingType(SamplingType.UNIFORM)"/>
          </div>
        </div>
      </div>

      <div class="collapse-panel">
        <div class="collapse-a">
          <div>
            <p><b>{{ $t('message.PointCloud.simplifyOption') }}</b></p>
          </div>
          <div :id="collapseId2" @click="foldClick2">
                    <span class="cursor-pointer" :class="[{'cursor-pointer': !disabled2}]">
                        <i :class="['fa', collapse2 ? 'fa-angle-up' : 'fa-angle-down']"/>
                    </span>
          </div>
        </div>
        <div v-show="!collapse2">
          <div>
            <el-checkbox v-model="params.deleted"
                             :label="$t('message.PointCloud.deleteForever')"/>
          </div>
        </div>
      </div>

      <div class="collapse-panel">
        <div class="collapse-a">
          <div>
            <p><b>{{ $t('message.PointCloud.detail') }}</b></p>
          </div>
          <div :id="collapseId3" @click="foldClick3">
                    <span class="cursor-pointer" :class="[{'cursor-pointer': !disabled3}]">
                        <i :class="['fa', collapse3 ? 'fa-angle-up' : 'fa-angle-down']"/>
                    </span>
          </div>
        </div>
        <div v-show="!collapse3">
          <div class="detail">
            <P style="margin-bottom: 10px">{{ $t('message.PointCloud.originPoints') }}：{{ params.origin }}</P>
          </div>
        </div>
      </div>

      <div class="el-dialog--center mt-3">
        <el-button id="buttonCalculate"
                   size="small"
                   type="calculate"
                   :disabled="!allowPreview"
                   @click="calculate"
                   :loading="params.calculating">
          <slot v-if="params.calculating" name="calculating">{{ $t('message.PointCloud.calculating') }}
          </slot>
          <slot v-else name="calculate">{{ $t('message.PointCloud.calculate') }}</slot>
        </el-button>
        <el-button id="butonReset"
                   size="small"
                   type="info"
                   :disabled="!allowReset"
                   @click="reset">
          <slot name="calculating">{{ $t('message.PointCloud.reset') }}
          </slot>
        </el-button>
      </div>
    </template>
    <template>
      <div class="dialog-footer pt-1 pb-2 pl-2 pr-2">
        <el-button id="buttonApply"
                   ref="applyButton"
                   type="primary"
                   class="dialog-footer__apply-button"
                   :disabled="!allowConfirm"
                   @click="applyCmd"
                   @keyup.enter.native="applyCmd">
          {{ $t('message.PointCloud.apply') }}
        </el-button>
        <el-button id="buttonConfirm"
                   ref="confirmButton"
                   type="primary"
                   class="dialog-footer__confirm-button"
                   :disabled="!allowConfirm"
                   @click="confirmCmd"
                   @keyup.enter.native="confirmCmd">
          {{ $t('message.PointCloud.confirm') }}
        </el-button>
        <el-button id="buttonClose"
                   ref="closeButton"
                   class="dialog-footer__close-button"
                   :disabled="false"
                   @click="closeCmd"
                   @keyup.enter.native="closeCmd">
          {{ $t('message.PointCloud.close') }}
        </el-button>
      </div>
    </template>
  </div>
</template>

<script>
import InputVariable from "../../../util/InputVariable";
import {ParamBoundary} from "../../../Command/pointCloud/ParamBoundary";
import {pointCloudSimplifyCommand} from "../../../Command/pointCloud/PointCloudSimplifyCommand";
import {BoolType, SamplingType, samplingTypeMap} from "../../../Command/pointCloud/PointCloudType";
import {i18n} from "../../js/util/I18n";
import {ElementType} from "../../../modeling/TypeDefine";

let IdCount = 0;
export default {
  name: "CmdDlgPointCloudSimplify",
  data() {
    IdCount++;
    return {
      disabled1: false,
      disabled2: false,
      disabled3: false,
      collapseId1: 'dialogCollapsed1',
      collapseId2: 'dialogCollapsed1',
      collapseId3: 'dialogCollapsed1',
      collapse1: false,
      collapse2: true,
      collapse3: false,
      optionApplyOrConfirm: 'Apply',
      showConfirm: true,
      params: {
        pointCloudList: [],                // 点云列表
        queryListActiveMap: {
          pointCloudList: 1,
        },
        lockedProperty: {
          pointCloudList: false,
        },
        reduction: new InputVariable(20), // 缩减比例
        reductionScrollValue: 20,                            // 缩减比例滑动条的值
        reductionBoundary: new ParamBoundary(0, true, 100, true),                 // 缩减比例范围
        target: new InputVariable(0), // 目标点数
        targetBoundary: new ParamBoundary(0, true),  // 目标点数范围
        origin: 0,                         // 原始点数
        samplingType: SamplingType.RANDOM, // 采样方式
        samplingSelected: {
          random: true,
          curvature: false,
          uniform: false,
        },
        previewUUID: null,
        deleted: true,                  // 是否永久删除简化的点
        calculating: false,                // 是否在计算中
        isPreviewed: false,               // 是否已经预览过了
        needCalculate: true,         // 是否需要点击计算
      },
      pointCloudElement: null, // 点云元素，设置显隐状态用
    }
  },
  created() {
    pointCloudSimplifyCommand.init(500,250,800,() => {
      this.changePluginContainerHeight(120);
      this.pickFeatureNodeMode();
      this.pickElementMode();
    });
  },
  beforeDestroy() {
    this.clearPreview();
    pointCloudSimplifyCommand.closeActiveCmd();
  },
  methods: {
    pickFeatureNodeMode() {
      let filterSelectTypes = [ElementType.POINTCLOUD];
      pointCloudSimplifyCommand.setSelectType(filterSelectTypes);
      pointCloudSimplifyCommand.handlePickFeatureNode(res => {
        if(res?.feature?.type.includes('PointCloud')) {
          let type = res?.feature?.type;
          let name = res?.feature?.name;
          if (type.includes('PointCloud') && !type.includes('Reconstruction')) {
            if (this.params.pointCloudList.length > 0) {
              this.params.pointCloudList.length = 0;
            }
            pointCloudSimplifyCommand.getElementsByFeatureNames([name], elements => {
              if(elements?.data?.elements[0]?.id) {
                console.log('PointCloud Elements: ' + elements);
                this.params.pointCloudList.push(res.feature);
                let element = elements.data.elements[0];
                this.pointCloudElement = element;
                this.initParams();
              } else {
                let element = this.pointCloudElement;
                pointCloudSimplifyCommand.clearAllHighLight();
                pointCloudSimplifyCommand.highLightElements([element.id]);
              }
            });
          } else if(this.params.pointCloudList.length > 0 && this.pointCloudElement) {
            let element = this.pointCloudElement;
            pointCloudSimplifyCommand.clearAllHighLight();
            pointCloudSimplifyCommand.highLightElements([element.id]);
          } else {
            pointCloudSimplifyCommand.clearAllHighLight();
          }
        } else if(this.params.pointCloudList.length > 0 && this.pointCloudElement) {
          let element = this.pointCloudElement;
          pointCloudSimplifyCommand.clearAllHighLight();
          pointCloudSimplifyCommand.highLightElements([element.id]);
        }
      });
    },
    pickElementMode() {
      let filterSelectTypes = [ElementType.POINTCLOUD];
      pointCloudSimplifyCommand.setSelectType(filterSelectTypes);
      pointCloudSimplifyCommand.handlePickElement(res => {
        if(res?.element[0]?.element) {
          let element = res?.element[0]?.element
          this.pointCloudElement = element;
          let name = element.name;
          let featureName = name.slice(0, name.indexOf(this.$t('message.PointCloud.elementName')));
          pointCloudSimplifyCommand.getFeaturesByNames([featureName], result => {
            if(result?.data?.features[0]?.id) {
              let feature = result?.data?.features[0];
              if (this.params.pointCloudList.length > 0) {
                this.params.pointCloudList.length = 0;
              }
              this.params.pointCloudList.push(feature);
              this.initParams();
            }
          });
        } else if(this.params.pointCloudList.length > 0 && this.pointCloudElement) {
          let element = this.pointCloudElement;
          pointCloudSimplifyCommand.clearAllHighLight();
          pointCloudSimplifyCommand.highLightElements([element.id]);
        }
      });
    },
    //拾取后参数初始化
    initParams() {
      let pointCloud = this.pointCloudElement;
      this.params.origin = pointCloud.params.pointNum;
      this.params.targetBoundary = new ParamBoundary(0, true, pointCloud.params.pointNum, true);
      // 缩减比例和目标点数先设置了哪个就用哪个的值
      if (this.params.reduction?.variableValue > 0) {
        this.changeReduction(this.params.reduction);
      } else if (this.params.target?.variableValue > 0) {
        this.changeTarget(this.params.target);
      } else {
        // 拾取点云后如未设定参数则将目标点数默认设置为原始点数
        this.params.target = new InputVariable(0);  // 防止目标点数为空
        this.params.target.variableValue = this.params.origin;
        this.changeTarget(this.params.target.variableValue);
      }
    },
    //计算按钮
    calculate() {
      this.params.calculating = true;
      this.preview();
    },
    //预览
    preview() {
      if(!this.checkParam()){
        return;
      }
      let config = this.getCommandParams();
      pointCloudSimplifyCommand.previewPointCloudSimplify(config,() => {
        this.params.calculating = false;
        this.params.isPreviewed = true;
        this.params.needCalculate = false;
      });
      let params = {
        elementId: this.pointCloudElement.id,
        visible: false,
      }
      //隐藏原模型
      pointCloudSimplifyCommand.setPointCloudSimplifyVisible(params);
    },
    getSamplingTypeText(samplingType) {
      return i18n.getMessage('message.pointCloud.' + samplingTypeMap[samplingType]);
    },
    // 改变缩减比例
    changeReduction(value) {
      if(this.params.reduction.variableValue < 0 ) {
        this.params.reduction.variableValue = 0;
      }else if(this.params.reduction.variableValue > 100 ) {
        this.params.reduction.variableValue = 100;
      }
      this.params.reductionScrollValue = this.params.reduction.variableValue;
      if (this.params.pointCloudList.length < 1 || !value) {
        return;
      }
      let pointCloud = this.pointCloudElement;
      if (!this.params.target) {
        this.params.target = new InputVariable(0);
      }
      let target = Math.floor(pointCloud.params.pointNum * (1 - this.params.reduction.variableValue * 0.01));
      this.params.target.variableValue = target > 0 ? target : 1;
      // 如果不需要点击计算
      if (!this.params.needCalculate) {
        this.preview();
      }
    },
    //改变目标点数
    changeTarget(value) {
      // 修改参数后取消预览效果
      // this.reset();
      if (this.params.pointCloudList.length < 1 || !value) {
        return;
      }
      let pointCloud = this.pointCloudElement;
      if (!this.params.reduction) {
        this.params.reduction = new InputVariable(0);
      }
      if(this.params.target.variableValue <= 0 ) {
        this.params.target.variableValue = 1;
      } else if(this.params.target.variableValue > pointCloud.params.pointNum ) {
        this.params.target.variableValue = pointCloud.params.pointNum;
      }
      this.params.reduction.variableValue = Math.round(100 - this.params.target.variableValue * 100 / pointCloud.params.pointNum);
      this.params.reductionScrollValue = this.params.reduction.variableValue;
      // 如果不需要点击计算
      if (!this.params.needCalculate) {
        this.preview();
      }
    },
    //改变缩减比例滑动条的值
    changeReductionScrollValue(value) {
      if (!this.params.reduction) {
        this.params.reduction = new InputVariable(value);
      } else {
        this.params.reduction.variableValue = value.currentTarget._value;
      }
      this.changeReduction(this.params.reduction);
    },
    //修改采样类型
    changeSamplingType(value) {
      this.params.samplingSelected.random = false;
      this.params.samplingSelected.curvature = false;
      this.params.samplingSelected.uniform = false;

      let k = samplingTypeMap[value];
      this.params.samplingSelected[k] = true;
      this.params.samplingType = value;
      // 修改参数后取消预览效果
      this.reset();
      this.params.needCalculate = true;
    },
    //重置
    reset() {
      this.clearPreview();
      this.params.isPreviewed = false;
    },
    //清除预览
    clearPreview() {
      if (this.pointCloudElement) {
        // 清除预览后重新显示原模型
        let params = {
          elementId: this.pointCloudElement.id,
          visible: true,
        }
        pointCloudSimplifyCommand.setPointCloudSimplifyVisible(params);
      }
      pointCloudSimplifyCommand.clearPreViewPointCloudSimplify();
      pointCloudSimplifyCommand.clearPreview();
    },
    //应用
    applyCmd() {
      this.optionApplyOrConfirm = 'Apply';
      this.confirm();
    },
    //确定
    confirmCmd() {
      this.optionApplyOrConfirm = 'Confirm';
      this.confirm();
    },
    //确定和应用
    confirm() {
      if(!this.checkParam()){
        return;
      }
      let config = this.getCommandParams();
      pointCloudSimplifyCommand.createPointCloudSimplify(config,() => {
        this.params.calculating = false;
        this.params.isPreviewed = false;
        this.params.needCalculate = true;
        this.resetParams();
        pointCloudSimplifyCommand.clearPreViewPointCloudSimplify();
        pointCloudSimplifyCommand.clearPreview();
        if(this.optionApplyOrConfirm === 'Confirm') {
          pointCloudSimplifyCommand.closeActiveCmd();
        }
      });
    },
    //获取发送命令的参数
    getCommandParams() {
      let pointCloudTopoId = this.pointCloudElement.params.entityRefTopoId;
      let reduction = this.params.reduction.variableValue;
      let target = this.params.target;
      let samplingType = this.params.samplingType;
      let deleted = this.params.deleted ? BoolType.TRUE : BoolType.FALSE;

      return {
        pointCloudId: pointCloudTopoId,
        reduction: reduction,
        target: target,
        samplingType: samplingType,
        deleted: deleted,
      };
    },
    removeSelect(){
      pointCloudSimplifyCommand.clearAllHighLight();
      this.params.isPreviewed = false;
    },
    //安全检查
    checkParam() {
      if (this.params.pointCloudList.length < 1) {
        return false;
      }
      return true;
    },
    //关闭
    closeCmd() {
      this.clearPreview();
      pointCloudSimplifyCommand.closeActiveCmd();
    },
    resetParams() {
      this.params.pointCloudList = [];
      this.params.reductionScrollValue = 0;
      this.params.reduction.variableValue = 20;
      this.changeReduction(this.params.reduction);
      this.pointCloudElement = null;
      this.params.samplingType = SamplingType.RANDOM; // 采样方式
      this.params. samplingSelected = {
        random: true,
        curvature: false,
        uniform: false,
      };
      this.params.deleted = true;
    },
    //控制折叠展开
    foldClick1() {
      if (this.disabled1) {
        return;
      }
      this.collapse1 = !this.collapse1;
    },
    foldClick2() {
      if (this.disabled2) {
        return;
      }
      this.collapse2 = !this.collapse2;
    },
    foldClick3() {
      if (this.disabled3) {
        return;
      }
      this.collapse3 = !this.collapse3;
    },
    changePluginContainerHeight(height) {
      pointCloudSimplifyCommand.changePluginContainerHeight(
        {minWidth: this.$el.clientWidth, maxHeight: 340 + height})
    },
    changeContainerHeight() {
      let height = 0;
      if(this.params.pointCloudList.length < 1) {
        height += 0;
      } else {
        height += 1;
      }
      if(this.collapse1) {
        height += 0;
      } else {
        height += 65;
      }
      if(this.collapse2) {
        height += 0;
      } else {
        height += 20;
      }
      if(this.collapse3) {
        height += 0;
      } else {
        height += 55;
      }
      this.changePluginContainerHeight(height);
    },
  },
  computed: {
    SamplingType() {
      return SamplingType;
    },
    allowPreview() {
      return !this.params.calculating
        && this.params.pointCloudList.length > 0
        && this.params.target
        && this.params.needCalculate
        && !this.allowReset;
    },
    allowConfirm() {
      return !this.params.calculating
        && this.params.pointCloudList.length > 0
        && !this.params.needCalculate
        && (this.params.target || this.params.isPreviewed);
    },
    allowReset() {
      return this.params.isPreviewed;
    }
  },
  watch: {
    'params.pointCloudList': {
      handler(newVal, oldVal) {
        this.changeContainerHeight();
      },
    },
    'collapse1': {
      handler(newVal, oldVal) {
        this.changeContainerHeight();
      },
    },
    'collapse2': {
      handler(newVal, oldVal) {
        this.changeContainerHeight();
      },
    },
    'collapse3': {
      handler(newVal, oldVal) {
        this.changeContainerHeight();
      },
    },
  }
}

</script>

<style scoped>

.root {
    font-size: var(--text-12);
}

.wrap {
    font-size: 12px;
}

.dialog-row {
    display: flex;
}

.reductionRange {
    margin-top: -7px;
}

.reductionRange input[type=range] {
    -webkit-appearance: none;
    height: 6px;
    width: 100%;
    border: 0px;
    background: var(--bg-color8);
    outline: none;
}

.reductionRange input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    height: 20px;
    width: 10px;
    background: var(--bg-color7);
    /*border-radius: 50% 50% 0 0;*/
    border: solid 1px rgba(0, 0, 0, 0.3);
    z-index: 1;
}

.reductionRange input[type=range]:hover {
    cursor: pointer;
}

.collapse-panel > .collapse-a {
    color: var(--text-color1);
    margin: 5px 0;
}

.collapse-a {
    display: flex;
    justify-content: space-between;
}

.detail {
    width: 100%;
    font-size: 13px;
    max-height: 10em;
    background-color: #eae8e8;
    overflow-y: auto;
    padding: 5px;
}

.el-button--calculate.is-active,
.el-button--calculate:active {
    background: #1777f5 !important;   /* 背景颜色*/
    color: #ffffff !important;        /* 字体颜色*/
    border-color: #9b9a9a !important; /* 边界颜色*/
}

.el-button--calculate:focus,
.el-button--calculate:hover {
    background: #1777f5 !important;   /* 背景颜色*/
    color: #ffffff !important;        /* 字体颜色*/
    border-color: #9b9a9a !important; /* 边界颜色*/
}

.el-button--calculate.is-disabled,
.el-button--calculate.is-disabled:hover {
    background: #92c2f3 !important;   /* 背景颜色*/
    color: #ffffff !important;        /* 字体颜色*/
    border-color: #9b9a9a !important; /* 边界颜色*/
}

.el-button--calculate {
    background: #3c8cf5 !important;   /* 背景颜色*/
    color: #ffffff !important;        /* 字体颜色*/
    border-color: #9b9a9a !important; /* 边界颜色*/
}

.dialog-footer {
    display: flex;
    justify-content: flex-end;
}

.dialog-footer >>> .el-button {
    font-size: 12px;
}

</style>
